﻿using Common.AspNetCore;
using Common.Infrastructure;
using Log.Api.Extensions;
using Log.Api.IService;
using Log.Api.LogModels;
using Log.Api.QueryModel;
using Log.Api.Utils;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Log.Api.Service
{
    /// <summary>
    /// XClinet包装扫码
    /// </summary>
    public class PackScanLogService : CommonService
    {
        ////private IBaseEsContextService esContextService;
        private IEsClientProviderService clientProvider;
        private string indexName = "minigrouppackscanlog";
        private readonly IOptions<EsConfig> config;
        private readonly bool isSaveByHttp;

        /// <summary>
        /// 索引名称
        /// </summary
        public PackScanLogService(IServiceProvider provider, IEsClientProviderService client, IConfiguration c, IOptions<EsConfig> config) : base(provider)
        {
            this.clientProvider = client;
            this.config = config;
            this.isSaveByHttp = LibSysUtils.ToBoolean(c["IsAddByHttp"]);
        }

        public ElasticClient GetClient()
        {
            return this.clientProvider.GetClient(indexName);
        }

        /// <summary>
        /// 插入
        /// </summary>
        public async Task<bool> InsertAsync(PackScanLogModel model)
        {
            if (this.isSaveByHttp)
            {
                await ElasticsearchUtils.SavePackScanLogAsync(this.config.Value.Urls[0], indexName, model);
                return true;
            }
            else
            {
                var client = GetClient();
                var response = await client.CreateDocumentAsync(model);
                return response.IsValid;
            }
        }

        /// <summary>
        /// 根据Id删除数据
        /// </summary>
        public bool DeleteById<T>(string id) where T : class
        {
            var client = GetClient();
            var response = client.Delete<T>(id);
            return response.IsValid;
        }

        /// <summary>
        /// 根据条件获取日志
        /// </summary>
        /// <param name="parameter"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<PackScanLogModel> GetLogPage(PackScanLogQuery query)
        {
            var client = GetClient();
            var response = client.Search<PackScanLogModel>(s => s.Query(q => q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
            && q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
            && q.Match(w => w.Field(f => f.Result).Query(query.Result))
             && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))
             && +q.DateRange(d => d.Field(f => f.CT).GreaterThanOrEquals(query.BeginTime).LessThan(query.EndTime))).Sort(s => s.Descending(d => d.CT)).From((query.PageIndex - 1) * query.PageSize).Take(query.PageSize));
            return response.Documents.ToList();
        }

        /// <summary>
        /// 根据条件获取日志汇总数据
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public PackScanTotalLogModel GetTotalLogs(PackScanLogQuery query)
        {
            var result = new PackScanTotalLogModel();
            var client = GetClient();
            var response = client.Search<PackScanLogModel>(s => s.Query(q =>
                q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
                && q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
                && q.Match(w => w.Field(f => f.Result).Query(query.Result))
                && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))
                && +q.DateRange(d => d.Field(f => f.CT).GreaterThanOrEquals(query.BeginTime).LessThan(query.EndTime))).Take(query.TotalCount));
            var list = response.Documents.ToList();
            ////扫码数量
            result.ScanQty = list.Count;
            ////合格数量
            result.QualifiedQty = list.Where(c => c.Result != "NG" && c.Result2 != "NG" && c.Result3 != "NG").Count();
            ////不合格数量
            result.UnqualifiedQty = list.Where(c => c.Result == "NG" || c.Result2 == "NG" || c.Result3 == "NG").Count();
            return result;
        }

        /// <summary>
        /// 根据条件获取日志
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public List<PackScanLogModel> GetLogs(PackScanLogQuery query)
        {
            var client = GetClient();
            var response = client.Search<PackScanLogModel>(s => s.Query(q => q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
             && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))));
            var result = response.Documents.ToList();
            return result;
        }

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <returns></returns>
        public long GetTotalCount(PackScanLogQuery query)
        {
            var client = GetClient();
            ISearchResponse<PackScanLogModel> response = null;

            if (query.ScanValueType == 1)
            {
                response = client.Search<PackScanLogModel>(s => s.Query(q => q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
            && q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
            && q.Match(w => w.Field(f => f.Result).Query(query.Result))
             && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))));
            }
            else if (query.ScanValueType == 0)
            {
                response = client.Search<PackScanLogModel>(s => s.Query(q => q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
           && q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
           && q.Match(w => w.Field(f => f.Result2).Query(query.Result))
            && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))));
            }
            else
            {
                response = client.Search<PackScanLogModel>(s => s.Query(q => q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
           && q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
           && q.Match(w => w.Field(f => f.Result3).Query(query.Result))
            && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))));
            }

            return response.Total;
        }

        /// <summary>
        /// 获取总数
        /// </summary>
        /// <returns></returns>
        public long GetTotalCountByPage(PackScanLogQuery query)
        {
            var client = GetClient();
            var response = client.Search<PackScanLogModel>(s => s.Query(q => q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
            && q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
            && q.Match(w => w.Field(f => f.Result).Query(query.Result))
             && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))
            && +q.DateRange(d => d.Field(f => f.CT).GreaterThanOrEquals(query.BeginTime).LessThan(query.EndTime))));
            return response.Total;
        }

        /// <summary>
        /// 获取所有日志
        /// </summary>
        /// <returns></returns>
        public List<PackScanLogModel> GetAllLoges()
        {
            var client = GetClient();
            var searchDescriptor = new SearchDescriptor<PackScanLogModel>();
            searchDescriptor = searchDescriptor.Query(p => p.MatchAll());
            var response = client.Search<PackScanLogModel>(searchDescriptor);
            return response.Documents.ToList();
        }

        /// <summary>
        /// 删除指定日志数据
        /// </summary>
        /// <returns></returns>
        public bool DeleteByQuery(PackScanLogQuery query)
        {
            var client = GetClient();
            var response = client.Search<PackScanLogModel>(s => s.Query(q => (q.Match(w => w.Field(f => f.ScanType).Query(query.ScanType))
             || q.Match(w => w.Field(f => f.OrderNo).Query(query.OrderNo))
             || q.Match(w => w.Field(f => f.Result).Query(query.Result)))
              && q.Match(w => w.Field(f => f.ApiKey).Query(query.ApiKey))
              && +q.DateRange(d => d.Field(f => f.CT).GreaterThanOrEquals(query.BeginTime).LessThan(query.EndTime))));
            return response.IsValid;
        }
    }
}
